﻿// ┌────────────────────────────────────────────────
// │  control class :: requirement
// │  1 :: rms.core.js
// │  2 :: 
// │  3 :: 
// │  4 :: 
// │  5 ::
// └────────────────────────────────────────────────
//=====================================================================================================
// Class Base Control Contructor
//=====================================================================================================
(function (RMS) {
    function BaseEntry(settings) {
        this.init(settings);
    };
    //======================================================
    BaseEntry.prototype.extend = function () {
        var baseClass = this.constructor;
        function Entry() {
            baseClass.apply(this, arguments);
        }

        function inherit(Child, Parent) {
            function Bridge() { };

            Bridge.prototype = Parent.prototype;
            Child.prototype = new Bridge();
            Child.prototype.constructor = Child;
            return Child;
        };

        return inherit(Entry, baseClass);
    };

    BaseEntry.prototype.init = function () {
        throw Error('BaseControl init() method unimplemented');
    };

    BaseEntry.prototype.binding = function () {
        throw Error('BaseControl binding() method unimplemented');
    };

    BaseEntry.prototype.load = function () {
        throw Error('BaseControl load() method unimplemented');
    };

    BaseEntry.prototype.getInstance = function () {
        throw Error('BaseControl getInstance() method unimplemented');
    };

    BaseEntry.prototype.updateSettings = function () {
        throw Error('BaseControl updateSettings() method unimplemented');
    };

    BaseEntry.prototype.getSettings = function () {
        throw Error('BaseControl getSettings() method unimplemented');
    };
    //======================================================
    //something here: enable/disable,...
    RMS.BaseEntry = BaseEntry;
})(RMS);
//=====================================================================================================
//  Entry Constructor Class
//=====================================================================================================
(function (RMS) {
    //public properties
    var Entry = RMS.BaseEntry.prototype.extend(),
        defaults = {},
        controls,
        requests,
        $entry;
    //======================================================
    //start public function
    Entry.prototype.init = function (settings) {
        if (settings) {
            defaults = $.extend(true, defaults, settings);
        }
        //define
        $entry = $(defaults.id);
        controls = {};
        requests = [];
        //init meta data control
        initMeta();
        //init request data source
        initRequest(function (data) {             
            for (var i in controls) {
                //init with data source
                if( controls[i].requestIdx){
                    controls[i].settings.source = data[controls[i].requestIdx]; 
                }
                
                controls[i].$Control = new RMS.CControl(controls[i].settings);                    
            }                    
        });        
    };

    Entry.prototype.binding = function () {
        console.log('::binding');
    };

    Entry.prototype.getSettings = function () {
        console.log('::getSettings');
        return defaults;
    };

    Entry.prototype.load = function () {
        console.log('::load');
    };

    Entry.prototype.updateSettings = function (settings) {
        if (settings) {
            defaults = $.extend(true, defaults, settings);
            this.load();
        }
    };
    //end public function
    //======================================================
    //start private function

    //data-meta
    function initMeta() {
        var val, meta; //index of request data table
        $entry.find('[' + RMS.consts.meta + ']').each(function (idx, el) {
            val = this.attributes[RMS.consts.meta].value;
            try{
                meta = JSON.parse(val);                                
            }catch(e){
                meta = RMS.pub.parseJson(val);
            }            
            if (meta) {
                if (meta.type) {
                    meta.controlType = meta.type;
                    delete meta.type;
                }
                meta.id = this.id;
                controls[this.id] = {
                    settings: meta
                };                                        
            }
            //clear
            this.attributes.removeNamedItem(RMS.consts.meta);
        });
    };

    function initRequest(callback) {
        var val, tempIdx;
        $entry.find('[' + RMS.consts.request + ']').each(function (idx, el) {
            val = this.attributes[RMS.consts.request].value;            
            if (val) {
                tempIdx = $.inArray(val, requests);                                
                if (tempIdx == -1) {
                    requests.push(val);
                    tempIdx = requests.length - 1;
                }                     
                if (typeof controls[this.id] != 'undefined') {
                    controls[this.id].requestIdx = tempIdx + 1;                    
                }
            }
            //clear
            this.attributes.removeNamedItem(RMS.consts.request);
        });

        //get request data
        var data = [];
        data.push([{ Description: 'Successfully'}]);
        data.push([{ ID: '1', Name: 'A', DefaultValue:false, Group:'PMSA' }, { ID: '2', Name: 'B', DefaultValue:true, Group:'SBB'}, { ID: '3', Name: 'C', DefaultValue:true, Group:'HSBC'}, { ID: '4', Name: 'D', DefaultValue:false, Group:'VGB'}]);
        data.push([
                  { icon: "../../images/mailIcon.png", label: "Mail", expanded: true, items: [
                  { icon: "../../images/calendarIcon.png", label: "Calendar" },
                  { icon: "../../images/contactsIcon.png", label: "Contacts" }
                ]},
                {
                    icon: "../../images/folder.png", label: "Inbox", expanded: true, items: [
                     { icon: "../../images/folder.png", label: "Admin" },
                     { icon: "../../images/folder.png", label: "Corporate" },
                     { icon: "../../images/folder.png", label: "Finance" },
                     { icon: "../../images/folder.png", label: "Other" },
                    ]
                }
            ]);        
        if(callback){
            callback(data);    
        }                          
    };

    function initControl() {
        controls[id] = new RMS.CControl({ controlType: meta.type, id: id });
    };
    //end private function
    //======================================================    
    RMS.CEntry = Entry;
})(RMS);
//=====================================================================================================
//  Dynamic Entry/Control Constructor Class
//=====================================================================================================
// ┌────────────────────────────────────────────────
// │  control class :: requirement
// │  1 :: rms.core.js
// │  2 :: 
// │  3 :: 
// │  4 :: 
// │  5 ::
// └────────────────────────────────────────────────
//=====================================================================================================
// Dynamic Template/Control Contructor
//=====================================================================================================
(function (RMS) {
    //public properties
    var DynamicTemplate = function (settings) {
        this.init(settings);
    };
    var $entry,
        $template;
    var datetime;
    //======================================================
    DynamicTemplate.prototype.isCompleted = false;

    DynamicTemplate.prototype.init = function (settings) {
        if (settings) {
            this.settings = $.extend(true, {
                childName: 'items',
                meta: {
                    theme: {
                        level1: 'bootstrap',
                        level2: 'bootstrap'
                    },
                    breakByLevel: 2
                }
            }, settings);
        }
        $entry = $(this.settings.id);
        $entry.attr({ level: 0 });

        $template = $entry.clone();

        datetime = new Date().getTime();
        var _this = this;
        if (_this.settings.url) {
            RMS.Ajax({
                url: _this.settings.url,
                type: 'post',
                data: {},
                success: function (data) {
                    if (data) {
                        data = new RMS.CCSV2JSON(data).toJson();
                        if (data && data[1]) {
                            dynamic($entry, data, _this);
                        }
                    }
                }
            });
        }
        else if (_this.settings.data) {
            dynamic($entry, _this.settings.data, _this);
        }
        else {
            console.log('::data is undefined');
        }
    };

    DynamicTemplate.prototype.loadComplete = function (instance) {
        this.isCompleted = true;
        if (this.settings.callback) {
            this.settings.callback(instance);
        }
    };
    //private function  
    function dynamic($entry, data, instance) {
        data = RMS.pub.convert2TreeData(data, instance.settings.childName);
        //console.log(data);
        switch (instance.settings.type) {
            case 'nav': //nav tree
                dynamicNav($entry, data, instance);
                break;
            case 'nav1': //nav 1 level
                dynamicNav1($entry, data, instance);
                break;
            case 'menu': //menu tree
                dynamicMenu($entry.children(), data, instance);
                break;
            case 'product': //product
                dynamicProduct($entry, data, instance);
                break;
            case 'products': //product
                dynamicProducts($entry, data, instance);
                break;
            case 'cat': //categories
                dynamicCategories($entry, data, instance);
                break;
            case 'news': //news
                dynamicNews($entry, data, instance);
                break;
            default:

                break;
        }
        instance.loadComplete(instance);
        console.log('::end callback', new Date().getTime() - datetime);
    };

    function dynamicNav($entry, data, instance) {
        var html = $entry[0].innerHTML,
            $div = $('<div>'),
            $entryClone,
            $titleClone,
            $contentClone,
            titleHtml,
            contentHtml;

        $titleClone = $entry.find('div:first').clone(true);
        $contentClone = $entry.find('div:first').next().clone(true);

        titleHtml = $titleClone[0].innerHTML;
        contentHtml = $contentClone[0].innerHTML;

        $entry.empty();
        $entryClone = $entry.clone(true);

        getNavHtml($entry, data);

        console.log('::end generate', new Date().getTime() - datetime);

        function getNavHtml($p, data) {
            for (var i = 0; i < data.length; i++) {
                //header               
                $p.append(nano(titleHtml, data[i]));
                var $d = $div.clone();
                $p.append($d);
                if (data[i][instance.settings.childName] && data[i][instance.settings.childName].length) {
                    var $clone = $entryClone.clone();
                    //add current level
                    $clone.attr('level', data[i]._level + 1);
                    $d.append($clone);
                    getNavHtml($clone, data[i][instance.settings.childName]);
                }
            }

            var level = $p.attr('level'),
                settings = {};
            if (typeof level != 'undefined') {
                if (level > 0) {
                    settings.expandMode = 'single';
                }
                $p.removeAttr('level');
                if (instance.settings.meta && instance.settings.meta.theme) {
                    if (typeof instance.settings.meta.theme['level' + level] != 'undefined') {
                        settings.theme = instance.settings.meta.theme['level' + level];
                    }
                }
            }
            if (Object.keys(settings).length) {
                $p.attr(RMS.consts.settings, JSON.stringify(settings));
            }
        };
    };

    function dynamicNav1($entry, data, instance) {
        var html = $entry[0].innerHTML,
            $div = $('<div>'),
            $titleClone,
            $contentClone,
            titleHtml,
            contentHtml;

        $titleClone = $entry.find('div:first').clone(true);
        $contentClone = $entry.find('div:first').next().clone(true);

        titleHtml = $titleClone[0].outerHTML;
        contentHtml = $contentClone.find('ul')[0].innerHTML;

        $entry.empty();
        $titleClone.empty();
        $contentClone.find('ul').empty();

        getNav1Html($entry, data, titleHtml);

        console.log('::end generate', new Date().getTime() - datetime);

        function getNav1Html($p, data, template) {
            for (var i = 0; i < data.length; i++) {
                //header               
                $p.append(nano(template, data[i]));
                if (data[i][instance.settings.childName] && data[i][instance.settings.childName].length) {
                    var $clone = $contentClone.clone();
                    //add current level                    
                    $p.append($clone);
                    getNav1Html($clone.find('ul'), data[i][instance.settings.childName], contentHtml);
                }
            }
        };
    };

    function dynamicMenu($el, data, instance) {
        var html = $el[0].innerHTML,
            $elClone;

        $el.empty();
        $elClone = $el.clone();

        getMenuHtml($el, data);

        console.log('::end generate', new Date().getTime() - datetime);

        function getMenuHtml($p, data) {
            for (var i = 0; i < data.length; i++) {
                $p.append(nano(html, data[i]));
                if (data[i][instance.settings.childName] && data[i][instance.settings.childName].length) {
                    var $clone = $elClone.clone();
                    //add current level
                    $clone.attr('level', data[i]._level + 1);
                    $p.find('li#' + data[i].ID).append($clone);
                    getMenuHtml($clone, data[i][instance.settings.childName]);
                }
            }
        };
    };

    function dynamicProduct($el, data, instance) {
        console.log('product')
    };

    function dynamicProducts($el, data, instance) {
        console.log('products')
    };

    function dynamicCategories($el, data, instance) {
        console.log('Categories')
    };

    function dynamicNews($el, data, instance) {
        console.log('News')
    };

    function nano(template, data) {
        return template.replace(/\{([\w\.]*)\}/gi, function (str, key) {
            var keys = key.split("."), v = data[keys.shift()];
            for (var i = 0; i < keys.length; i++) v = v[this];
            return (typeof v !== "undefined" && v !== null) ? v : "";
        });
    };

    RMS.CDynamicTemplate = DynamicTemplate;
})(RMS);